package avicit.bdp.dcs.json.service.reader;

import avicit.bdp.common.datasource.ApiDataSource;
import avicit.bdp.common.datasource.BaseDataSource;
import avicit.bdp.common.datasource.DataSourceFactory;
import avicit.bdp.common.dto.api.APIHttpAuth;
import avicit.bdp.common.dto.api.APIHttpDefinition;
import avicit.bdp.common.dto.api.IncrementParam;
import avicit.bdp.common.service.dto.DataSourceDTO;
import avicit.bdp.common.service.service.DataSourceService;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.core.util.json.JSONUtils;
import avicit.bdp.dcs.job.dto.JobDTO;
import avicit.bdp.dcs.plugin.BaseDataxParam;
import avicit.bdp.dcs.plugin.api.param.ApiDataxParam;
import avicit.bdp.dcs.task.dto.ColumnMappingDto;
import avicit.bdp.dcs.task.dto.TaskDTO;
import avicit.bdp.dcs.task.service.ApiDefinitionService;
import cn.hutool.core.bean.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ApiReaderBuilder {

  @Autowired private ApiDefinitionService apiDefinitionService;
  @Autowired private DataSourceService dataSourceService;

  private static final String TYPE = "type";
  private static final String NAME = "name";

  /** 构建API采集Reader */
  public BaseDataxParam buildReaderByAPI(TaskDTO taskDTO, JobDTO jobDTO) throws Exception {
    APIHttpDefinition apiHttpDefinition = apiDefinitionService.getAPIHttpDefinition(jobDTO.getId());

    DataSourceDTO dataSourceDTO =
        dataSourceService.queryDataSourceById(jobDTO.getSrcDatasourceId());
    if (dataSourceDTO != null && dataSourceDTO.getDatasourceType().equals(Constants.DB_TYPE_API)) {
      BaseDataSource baseDataSource =
          DataSourceFactory.getDatasource(
              Constants.DB_TYPE_API, dataSourceDTO.getConnectionParams());
      ApiDataSource apiDataSource = (ApiDataSource) baseDataSource;
      apiHttpDefinition.setUrl(
          apiDataSource.getUrl() + Constants.SINGLE_SLASH + apiHttpDefinition.getUrl());
      apiHttpDefinition.setAuthType(apiDataSource.getAuthType());
      APIHttpAuth apiHttpAuth = new APIHttpAuth();
      BeanUtil.copyProperties(apiDataSource, apiHttpAuth);
      apiHttpDefinition.setAuthParam(apiHttpAuth);

      // 添加增量时间变量参数
      if (apiHttpDefinition.isHaveIncrement()) {
        buildIncrementParam(apiHttpDefinition);
      }
    }

    ApiDataxParam dataxParam = new ApiDataxParam();
    dataxParam.setApiHttpDefinition(apiHttpDefinition);

    List<ColumnMappingDto> columnMappingDtoList =
        JSONUtils.toList(taskDTO.getMappingColumn(), ColumnMappingDto.class);
    List<Map<String, Object>> columnList = new ArrayList<>();
    for (ColumnMappingDto columnMappingDto : columnMappingDtoList) {
      Map<String, Object> map = new HashMap<>();
      if (StringUtils.isEmpty(columnMappingDto.getSrcColumnPrefix())) {
        map.put(NAME, columnMappingDto.getSrcColumnName());
      } else {
        map.put(
            NAME,
            columnMappingDto.getSrcColumnPrefix()
                + Constants.DOT
                + columnMappingDto.getSrcColumnName());
      }
      map.put(TYPE, columnMappingDto.getSrcColumnType());
      columnList.add(map);
    }

    dataxParam.setColumnList(columnList);

    return dataxParam;
  }

  /** 增量参数开始时间和结束时间用变量代替 */
  private void buildIncrementParam(APIHttpDefinition apiHttpDefinition) {
    IncrementParam incrementParam = apiHttpDefinition.getIncrementParam();
    incrementParam.setStartTime("${DATA_START_TIME}");
    incrementParam.setEndTime("${DATA_END_TIME}");
    apiHttpDefinition.setIncrementParam(incrementParam);
  }
}
